package cn.windfly.don.servlet;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import cn.windfly.don.Constant;
import cn.windfly.don.DonConfig;
import cn.windfly.don.DonUtil;
import cn.windfly.don.pojo.JsonResult;
import cn.windfly.util.DateUtil;
import cn.windfly.util.IOUtil;
import cn.windfly.util.JsonUtil;
import cn.windfly.util.NumberByteUtil;
import cn.windfly.util.bean.TypeMap;
import cn.windfly.util.exception.MessageException;
import javassist.ClassClassPath;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.CtMethod;
import javassist.Modifier;
import javassist.NotFoundException;
import javassist.bytecode.CodeAttribute;
import javassist.bytecode.LocalVariableAttribute;
import javassist.bytecode.MethodInfo;

@WebServlet(urlPatterns = { "*" + Constant.CONTROLLER_REQUEST_SUF })
public class DepndsOnNameServlet extends HttpServlet {

	private static final long serialVersionUID = -2362027817617758628L;

	/**
	 * 将map参数加入到requestAttribute的环境中
	 * 
	 * @param req
	 * @param params
	 */
	private void setMapKvToRequestAttribute(HttpServletRequest req, Map<String, Object> params) {

		for (Map.Entry<String, Object> entry : params.entrySet()) {
			String key = entry.getKey();
			req.setAttribute(key, entry.getValue());
		}
	}

	/**
	 * 设置content type，解决jetty9兼容IE9下样式不加载问题
	 * 
	 * @param req
	 * @param resp
	 */
	private void setMime(HttpServletRequest req, HttpServletResponse resp) {
		if (req.getRequestURI().endsWith(".css")) {
			resp.setContentType("text/css");
		}

		if (req.getRequestURI().endsWith(".js")) {
			resp.setContentType("application/javascript");
		}
	}

	/**
	 * 设置编码
	 * 
	 * @param req
	 * @param resp
	 * @throws UnsupportedEncodingException
	 */
	private void setEncoding(HttpServletRequest req, HttpServletResponse resp) throws UnsupportedEncodingException {
		req.setCharacterEncoding("UTF-8");
		resp.setCharacterEncoding("UTF-8");
	}

	/**
	 * * 返回值以类型为判断依据。<br/>
	 * String ：返回jsp页面，页面根目录地址固定为 /WEB-INF/jsp/ <br/>
	 * 对象类型：返回json字符串 <br/>
	 * 
	 * @param request
	 * @param response
	 * @param returnValue
	 * @param params
	 * @throws ServletException
	 * @throws IOException
	 */
	private void writeToClient(HttpServletRequest request, HttpServletResponse response, Object returnValue,
			Map<String, Object> params) throws ServletException, IOException {
		if (returnValue instanceof String) {
			String[] rs = returnValue.toString().split(":", 2);
			if (rs.length > 1) {
				String rString = rs[0].toLowerCase();
				if (rString.equals("redirect")) {
					response.sendRedirect(rs[1]);
				} else {
					response.getWriter().write(rs[1]);
				}
			} else {
				request.getRequestDispatcher("/WEB-INF/jsp/" + returnValue + ".jsp").forward(request, response);
			}
			// } else if (returnValue instanceof InputStream) {
			// String fileName = (String) params.get("InputStreamName");
			// if (params.get("InputStreamName") == null) {
			// throw new ServletException("没有 InputStreamName 参数映射");
			// }
			// response.setHeader("Content-Disposition", "attachment; filename="
			// + new String(fileName.getBytes("GB2312"), "iso-8859-1"));
			// ServletOutputStream outputStream = response.getOutputStream();
			// InputStream stream = (InputStream) returnValue;
			// int e;
			// while ((e = stream.read()) != -1) {
			// outputStream.write(e);
			// }
			// response.flushBuffer();
		} else if (returnValue == null) {
			// ignore
		} else {
			// String s = new Gson().toJson(returnValue);
			String s = JsonUtil.toJson(returnValue);
			if (request.getHeader("User-Agent").contains("MSIE") || request.getHeader("User-Agent").contains("rv:11")) {
				response.setContentType("text/html;charset=UTF-8");
			} else {
				response.setContentType("application/json;charset=UTF-8");
			}
			response.getWriter().write(s);
		}
	}

	/**
	 * 分析URI对应映射的类和方法
	 * 
	 * @param request
	 * @return string[] [0]类实例名，首字母小写，[1]方法名 ，首字母小写
	 */
	private String[] analyseControllerMethod(HttpServletRequest request) throws Exception {
		String servletPath = request.getServletPath();
		int lastIndexOf = servletPath.lastIndexOf("/");
		if (lastIndexOf < 1) {
			throw new Exception("请求地址格式不正确:" + servletPath);
		}
		servletPath = servletPath.replace(Constant.CONTROLLER_REQUEST_SUF, "");

		String controllerName = servletPath.substring(1, lastIndexOf) + Constant.CONTROLLER_CLASSNAME_SUF;
		String methodName = servletPath.substring(lastIndexOf + 1);

		return new String[] { controllerName, methodName };
	}

	/**
	 * 将request中的属性都放入到map中。
	 * 
	 * @param req
	 * @param params
	 */
	private void putAttributesToMap(HttpServletRequest req, Map<String, Object> params) {
		Enumeration<String> attributeNames = req.getAttributeNames();
		while (attributeNames.hasMoreElements()) {
			String s = attributeNames.nextElement();
			params.put(s, req.getAttribute(s));
		}
	}

	/**
	 * 解析parameter，将对应的key/value放置于对于的环境中，并加入到map
	 * <p>
	 * 如果key不是以P,S,R结尾的将忽略，并在控制台中打印日志.<br/>
	 * 如果是form流格式上传，则以iso8859-1格式接收文件<br/>
	 * <p/>
	 * </p>
	 * 
	 * @param req
	 * @param params
	 * @throws IOException
	 * @throws MessageException
	 */
	private void parseRequestParameterToMap(HttpServletRequest req, Map<String, Object> params)
			throws IOException, ServletException, MessageException {

		String contentType = req.getContentType();
		if (contentType != null && contentType.startsWith("multipart/form-data")) {
			// 取 boundary 标识值如: boundary=---------------------------7dd9510103dc
			String boundary = "--" + contentType.substring(contentType.indexOf("boundary=") + "boundary=".length());

			// 循环读取
			InputStream inputStream = req.getInputStream();

			// byte[] readAll = IOUtil.readAll(inputStream);
			// System.out.println("======================");
			// System.out.println(new String(readAll,"iso8859-1"));
			// System.out.println("======================");

			BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "iso8859-1"));

			reader.readLine(); // 跳过第一行 boundary
			readPostFormBodyNoFirstBoundary(reader, req, params, boundary);
			reader.close();

		} else if (contentType != null && contentType.equals("application/json")) {

			ServletInputStream inputStream = req.getInputStream();
			String sub = new String(IOUtil.readAll(inputStream), StandardCharsets.UTF_8);
			Map<String, ?> map = cn.windfly.util.JsonUtil.parseJson(sub);
			params.putAll(map);

		} else {
			Map<String, String[]> parameterNamesMap = req.getParameterMap();
			Iterator<Map.Entry<String, String[]>> parameterNames = parameterNamesMap.entrySet().iterator();
			while (parameterNames.hasNext()) {
				Map.Entry<String, String[]> next = parameterNames.next();
				String key = next.getKey();

				if (next.getValue().length > 1) {
					// StringBuilder sb = new StringBuilder();
					for (String s : next.getValue()) {
						// sb.append(s).append(",");
						putAttrToMapWithList(params, key, s);
					}
					// sb.setLength(sb.length() - 1);
					// params.put(key, sb.toString());
				} else {
					// params.put(key, next.getValue()[0]);
					putAttrToMapWithList(params, key, next.getValue()[0]);
				}
			}
		}
	}

	private void readPostFormBodyNoFirstBoundary(BufferedReader reader, HttpServletRequest req,
			Map<String, Object> params, String boundary) throws IOException, ServletException, MessageException {

		int fieldNameIndex = ("Content-Disposition: form-data; name=\"").length();

		String contentDisposition = reader.readLine(); // 取 Content-Disposition
		if (contentDisposition == null)
			return;
		if (!contentDisposition.contains("Content-Disposition: form-data; name=\"")) {
			readPostFormBodyNoFirstBoundary(reader, req, params, boundary);
			return;
		}
		String fieldName = contentDisposition.substring(fieldNameIndex,
				contentDisposition.indexOf("\"", fieldNameIndex));
		if (contentDisposition.contains("filename=")) {
			int index = contentDisposition.indexOf("filename=\"");
			int start = index + "filename=\"".length();
			int end = contentDisposition.indexOf("\"", start);
			String filename = new String(contentDisposition.substring(start, end).getBytes("ISO8859-1"));
			readPostFileField(reader, req, params, fieldName, filename, boundary);
		} else {
			readPostCommonField(reader, req, params, fieldName, boundary);
		}
	}

	private void readPostFileField(BufferedReader reader, HttpServletRequest req, Map<String, Object> params,
			String fieldName, String filename, String boundary) throws IOException, ServletException, MessageException {

		if (filename == null || filename.isEmpty()) {
			putAttrToMapWithList(params, fieldName, null);
			readPostFormBodyNoFirstBoundary(reader, req, params, boundary);
			return;
		}
		// 解决IE11下全路径问题
		if (filename.contains("\\")) {
			filename = filename.substring(filename.lastIndexOf("\\") + 1, filename.length());
		}
		// 文件后缀名限制
		List<String> typelist = DonConfig.getStringList("don.upload.type", ",");
		int indexOf = filename.lastIndexOf(".");
		if (indexOf == -1) {
			throw new MessageException(Constant.PARAM_UPLOAD_ERROR_FILETYPE);
		}
		String suffix = filename.substring(indexOf + 1).toLowerCase();
		if (!typelist.isEmpty() && !typelist.contains(suffix)) {
			throw new MessageException(Constant.PARAM_UPLOAD_ERROR_FILETYPE);
		}

		// 是流文件
		// 流文件，第一行 为属性名和完整文件名，第二行为流类型，第三行为空，第四行开始为内容
		// 跳过两行
		reader.readLine(); // 流类型 Content-Type: application/octet-stream
		reader.readLine(); // 空

		char[] chars = boundary.toCharArray();

		char[] temp = new char[chars.length]; // 可能最后结束符会多2位
		int b;
		// StringBuilder stringBuilder = new StringBuilder(req.getInputStream()
		// .available());
		//
		File path = new File(Constant.TEMP_PATH + UUID.randomUUID());
		path.mkdir();

		File nFile = new File(path, filename);
		FileOutputStream fileOutputStream = new FileOutputStream(nFile);
		ByteArrayOutputStream boStream = new ByteArrayOutputStream();
		while ((b = reader.read()) != -1) {
			if (boStream.size() > NumberByteUtil.readUnitByteSize(DonConfig.getString("don.upload.max", "10M"))) { // 11024*1024*10
				fileOutputStream.close();
				throw new MessageException(Constant.PARAM_UPLOAD_OVERFLOW_MSG); // 上传文件大于10M
			}
			if (b == chars[0]) {
				temp[0] = (char) b;
				boolean isEnd = true;
				int i;
				for (i = 1; i < chars.length; i++) {
					b = reader.read();
					temp[i] = (char) b;
					if (b != chars[i]) {
						isEnd = false;
						break;
					}
				}
				if (isEnd) {

					filename = new String(filename.getBytes("iso8859-1"), req.getCharacterEncoding());
					if (filename.isEmpty()) {
						params.put(fieldName, null);
					} else {
						putAttrToMapWithList(params, fieldName, nFile);
					}
					// 读取到行结束标识
					reader.readLine();

					break;
				} else {
					for (int j = 0; j <= i; j++) {
						// stringBuilder.append(temp[j]);
						boStream.write(temp[j]);
					}
				}
			} else {
				// stringBuilder.append((char) b);
				boStream.write(b);
			}
		}
		byte[] byteArray = boStream.toByteArray();
		if (byteArray.length > 0) {
			fileOutputStream.write(byteArray, 0, byteArray.length - 2);
		}
		fileOutputStream.close();
		readPostFormBodyNoFirstBoundary(reader, req, params, boundary);
	}

	@SuppressWarnings("unchecked")
	private void putAttrToMapWithList(Map<String, Object> params, String key, Object value) {
		Object obj = params.get(key);
		if (params.containsKey(key)) {
			if (obj instanceof List) {
				((List<Object>) obj).add(value);
			} else {
				ArrayList<Object> list = new ArrayList<>();
				list.add(value);
				list.add(obj);
				params.put(key, list);
			}
		} else {
			params.put(key, value);
		}
	}

	private void readPostCommonField(BufferedReader reader, HttpServletRequest req, Map<String, Object> params,
			String fieldName, String boundary) throws IOException, ServletException, MessageException {
		// 是普通属性
		// 非流文件，第一行 为属性名如： Content-Disposition: form-data;
		// name="a" 第二行为空，第三行为值
		// 跳过第二行
		reader.readLine();

		String value = null;
		int index = 0;
		StringBuilder sb = new StringBuilder();
		while ((value = reader.readLine()) != null && !value.startsWith(boundary)) {
			index++;
			if (index > 1) {
				sb.append(System.getProperty("line.separator"));
			}
			sb.append(value);
		}
		value = new String(sb.toString().getBytes("iso8859-1"), req.getCharacterEncoding());
		if (params.containsKey(fieldName)) {
			// params.put(fieldName, params.get(fieldName) + "," + value);
			putAttrToMapWithList(params, fieldName, value);
		} else {
			params.put(fieldName, value);
		}
		readPostFormBodyNoFirstBoundary(reader, req, params, boundary);
	}

	// KEY controllername+methodname VALUE instance,parameternames
	HashMap<String, Object[]> controllerCacheMap = new HashMap<String, Object[]>();

	@SuppressWarnings("unchecked")
	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// 设置编码
		setEncoding(req, resp);

		// 设置content type，解决jetty9兼容IE9下样式不加载问题
		setMime(req, resp);
		Object returnValue = null;
		try {
			// 取url,分析对应的controller和方法
			String[] contMeth = analyseControllerMethod(req);

			// 检查是否存在对应映射
			Method declaredMethod = null;
			Map<String, Object> injectClassMap = (Map<String, Object>) req.getSession().getServletContext()
					.getAttribute(Constant.INJECTCLASSMAP_SERVLET_CONTEXT);

			String controllerName = contMeth[0].replace("/", ".");
			String mehtodName = contMeth[1];
			Object controllerInstance = null;
			List<String> parameterNames = null;

			// // 从全局环境中取出对应的controller实例,先从缓存中取,没有再从全局中取
			// if
			// (controllerCacheMap.containsKey(controllerName+"."+mehtodName)) {
			// Object[] objs =
			// controllerCacheMap.get(controllerName+"."+mehtodName);
			// controllerInstance = objs[0];
			// parameterNames = (List<String>) objs[1];
			// }else {
			// boolean hasone = false;
			// // 全局中只要是类全名的部分到结尾相同就行
			// for (String confullname : injectClassMap.keySet()) {
			// if (confullname.endsWith("."+controllerName) ||
			// confullname.equals(controllerName)) {
			// if (hasone) {
			// throw new ServletException("有多个相同的Controller映射:"+controllerName);
			// }
			// hasone = true;
			// controllerInstance = injectClassMap.get(confullname);
			// }
			// }
			// if (controllerInstance!=null) {
			// parameterNames =
			// getMethodParamNames(controllerInstance.getClass(), mehtodName);
			// controllerCacheMap.put(controllerName+"."+mehtodName, new
			// Object[]{controllerInstance,parameterNames});
			// }
			//
			// }

			controllerInstance = injectClassMap.get(controllerName);
			if (controllerInstance == null) {
				throw new ServletException("没有映射的 Controller:" + controllerName);
			}
			// controllerInstance = controllerInstance.getClass().newInstance();
			parameterNames = getMethodParamNames(controllerInstance.getClass(), mehtodName);

			// declaredMethod =
			// controllerInstance.getClass().getMethod(contMeth[1], Map.class);
			// // 含父类
			Method[] methods = controllerInstance.getClass().getMethods();
			for (Method method : methods) {
				if (method.getName().equals(mehtodName)) {
					declaredMethod = method;
					break;
				}
			}
			if (declaredMethod == null) {
				throw new ServletException("没有映射的 方法:" + controllerName + "." + mehtodName);
			}

			// 解析parameter，将对应的key/value放置于对于的环境中，并加入到map
			Map<String, Object> params = new TypeMap();
			parseRequestParameterToMap(req, params);

			putAttributesToMap(req, params); // 将requesst属性置于map中

			Object[] mvalues = putRquestMethodParamentValue(declaredMethod, parameterNames, req, resp, params); // 给方法参数赋值

			returnValue = declaredMethod.invoke(controllerInstance, mvalues); // 执行方法取得返回值

			setMapKvToRequestAttribute(req, params); // 将map参数加入到requestAttribute的环境中

			writeToClient(req, resp, returnValue, params);// 根据返回值判断如何向客户端输出

		} catch (MessageException e) {
			IOUtil.readAll(req.getInputStream());
			String json = JsonUtil.toJson(JsonResult.newErrorResult(e.getMessage()));
			resp.getWriter().write(json);
			resp.getWriter().flush();
		} catch (Exception e) {
			if (e.getCause() instanceof MessageException) {
				IOUtil.readAll(req.getInputStream());
				String json = JsonUtil.toJson(JsonResult.newErrorResult(e.getCause().getMessage()));
				resp.getWriter().write(json);
				resp.getWriter().flush();
				return;
			}

			// 有异常则向浏览器输出固定错误信息
			if (returnValue == null) {
				// LogUtil.error(e);
				throw new ServletException(e);
			}
			// if (returnValue instanceof String) {
			// if (((String) returnValue).toLowerCase().startsWith("string:")) {
			// LogUtil.error(e.getMessage());
			// resp.getWriter().write(e.getMessage());
			// } else {
			// throw new ServletException(e);
			// }
			// } else {
			// resp.getWriter().write("{\"error\":\"" + e.getMessage() + "\"}");
			// }
		}
	}

	private Object[] putRquestMethodParamentValue(Method declaredMethod, List<String> parameterNames,
			HttpServletRequest req, HttpServletResponse resp, Map<String, Object> params) throws Exception {

		ArrayList<Object> values = new ArrayList<Object>();
		Class<?>[] parameterTypes = declaredMethod.getParameterTypes();

		if (parameterTypes.length != parameterNames.size()) {
			throw new Exception("方法类型和名称数量不一致");
		}

		for (int i = 0; i < parameterTypes.length; i++) {
			Class<?> pClass = parameterTypes[i];
			String pname = parameterNames.get(i);
			Object v = params.get(pname);
			if (v == null) {
				v = req.getAttribute(pname);
			}
			if (pClass == Map.class || pClass == TypeMap.class) {
				v = params;
			} else {
				v = simpleTurnValue(req, resp, pClass, v, params);
			}
			values.add(v);
		}

		return values.toArray();
	}

	/**
	 * 简单类型转换
	 * 
	 * @param req
	 * @param resp
	 * @param pClass
	 * @param v
	 * @param params
	 * @return
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 * @throws InvocationTargetException
	 * @throws IllegalArgumentException
	 * @throws IntrospectionException
	 */
	@SuppressWarnings("deprecation")
	private Object simpleTurnValue(HttpServletRequest req, HttpServletResponse resp, Class<?> pClass, Object v,
			Map<String, Object> params) throws InstantiationException, IllegalAccessException, IllegalArgumentException,
			InvocationTargetException, IntrospectionException {
		if (pClass == String.class) {
			if (v != null) {
				if (v instanceof File) {
					String filePath = DonUtil.copyUploadFileToDefaultDirs((File) v);
					v = filePath;
				} else {
					v = String.valueOf(v);
				}
			}
		} else if (pClass == int.class) {
			v = Integer.parseInt(v.toString());
		} else if (pClass == Integer.class) {
			if (v != null) {
				if (v.toString().isEmpty()) {
					v = null;
				} else {
					v = Integer.valueOf(v.toString());
				}
			}
		} else if (pClass == byte.class) {
			v = Byte.parseByte(v.toString());
		} else if (pClass == Byte.class) {
			if (v != null) {
				if (v.toString().isEmpty()) {
					v = null;
				} else {
					v = Byte.valueOf(v.toString());
				}
			}
		} else if (pClass == boolean.class) {
			v = Boolean.parseBoolean(v.toString());
		} else if (pClass == Boolean.class) {
			if (v != null) {
				if (v.toString().isEmpty()) {
					v = null;
				} else {
					v = Boolean.valueOf(v.toString());
				}
			}
		} else if (pClass == char.class) {
			v = (v.toString()).charAt(0);
		} else if (pClass == Character.class) {
			if (v != null) {
				if (v.toString().isEmpty()) {
					v = null;
				} else {
					v = (v.toString()).charAt(0);
				}
			}
		} else if (pClass == long.class) {
			if (v.toString().isEmpty()) {
				v = 0;
			} else {
				v = Long.valueOf(v.toString());
			}
		} else if (pClass == Long.class) {
			if (v != null) {
				if (v.toString().isEmpty()) {
					v = null;
				} else {
					v = Long.valueOf(v.toString());
				}
			}
		} else if (pClass == double.class) {
			if (v.toString().isEmpty()) {
				v = 0;
			} else {
				v = Double.parseDouble(v.toString());
			}
		} else if (pClass == Double.class) {
			if (v != null) {
				if (v.toString().isEmpty()) {
					v = null;
				} else {
					v = Double.valueOf(v.toString());
				}
			}
		} else if (pClass == float.class) {
			if (v.toString().isEmpty()) {
				v = 0;
			} else {
				v = Float.parseFloat(v.toString());
			}
		} else if (pClass == Float.class) {
			if (v != null) {
				if (v.toString().isEmpty()) {
					v = null;
				} else {
					v = Float.valueOf(v.toString());
				}
			}
		} else if (pClass == File.class) {
			if (v != null) {
				v = (File) v;
			}
		} else if (pClass == Date.class) {
			if (v != null) {
				if (v.toString().trim().isEmpty()) {
					v = null;
				} else if (v instanceof Date) {
					v = (Date) v;
				} else {
					if (v.toString().matches("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}")) {
						v = DateUtil.prase(v.toString().trim());
					} else if (v.toString().matches("\\d{4}-\\d{2}-\\d{2}")) {
						v = DateUtil.prase(v.toString().trim(), "yyyy-MM-dd");
					} else if (v.toString().matches("\\d{4}-\\d{2}-\\d{2} \\d{2}:\\d{2}")) {
						v = DateUtil.prase(v.toString().trim(), "yyyy-MM-dd HH:mm");
					} else if (v.toString().matches("\\d{4}-\\d{2}")) {
						v = DateUtil.prase(v.toString().trim(), "yyyy-MM");
					} else if (v.toString().matches("\\d{4}")) {
						v = DateUtil.prase(v.toString().trim(), "yyyy");
					} else if (v.toString().matches("\\d{2}:\\d{2}:\\d{2}\"")) {
						v = DateUtil.prase(v.toString().trim(), "HH:mm:ss");
					} else if (v.toString().matches("\\d{2}:\\d{2}\"")) {
						v = DateUtil.prase(v.toString().trim(), "HH:mm");
					} else {
						v = new Date(v.toString());
					}
				}

			}
		} else if (pClass == HttpServletRequest.class) {
			v = req;
		} else if (pClass == HttpServletResponse.class) {
			v = resp;
		} else if (pClass == HttpSession.class) {
			v = req.getSession();
			// } else if (pClass.getSuperclass() == Object.class
		} else {// 认为是pojo bean
			v = pClass.newInstance();

			BeanInfo beanInfo = Introspector.getBeanInfo(pClass, Object.class);
			PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors();
			for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
				Method writeMethod = propertyDescriptor.getWriteMethod();
				Object obj = params.get(propertyDescriptor.getName());
				if (obj != null) {
					writeMethod.invoke(v,
							simpleTurnValue(req, resp, propertyDescriptor.getPropertyType(), obj, params));
				}
			}

		}
		return v;
	}

	/**
	 * 获取方法参数名称，按给定的参数类型匹配方法
	 * 
	 * @param clazz
	 * @param method
	 * @param paramTypes
	 * @return
	 * @throws Exception 如果类或者方法不存在 如果最终编译的class文件不包含局部变量表信息
	 */
	public List<String> getMethodParamNames(Class<?> clazz, String method, Class<?>... paramTypes) throws Exception {

		ClassPool pool = getClassPool();
		CtClass cc = pool.get(clazz.getName());
		String[] paramTypeNames = new String[paramTypes.length];
		for (int i = 0; i < paramTypes.length; i++)
			paramTypeNames[i] = paramTypes[i].getName();
		CtMethod cm = cc.getDeclaredMethod(method, pool.get(paramTypeNames));
		return getMethodParamNames(cm);
	}

	public ClassPool getClassPool() {
		ClassPool classPool = ClassPool.getDefault();
		classPool.insertClassPath(new ClassClassPath(this.getClass()));
		return classPool;
	}

	/**
	 * 获取方法参数名称，匹配同名的某一个方法
	 * 
	 * @param clazz
	 * @param method
	 * @return
	 * @throws Exception 如果类或者方法不存在 如果最终编译的class文件不包含局部变量表信息
	 */
	public List<String> getMethodParamNames(Class<? extends Object> clazz, String method) throws Exception {

		ClassPool pool = getClassPool();
		CtClass cc = pool.get(clazz.getName());
		CtMethod cm = cc.getDeclaredMethod(method);
		return getMethodParamNames(cm);
	}

	/**
	 * 获取方法参数名称
	 * 
	 * @param cm
	 * @return
	 * @throws NotFoundException 如果最终编译的class文件不包含局部变量表信息
	 */
	protected static List<String> getMethodParamNames(CtMethod cm) throws Exception {
		CtClass cc = cm.getDeclaringClass();
		MethodInfo methodInfo = cm.getMethodInfo();
		CodeAttribute codeAttribute = methodInfo.getCodeAttribute();
		LocalVariableAttribute attr = (LocalVariableAttribute) codeAttribute.getAttribute(LocalVariableAttribute.tag);
		if (attr == null)
			throw new Exception("class:" + cc.getName() + " 不包含局部变量表信息，请使用编译器选项 javac -g:{vars}来编译源文件。");

		List<String> paramNames = new ArrayList<String>(cm.getParameterTypes().length);
		int pos = Modifier.isStatic(cm.getModifiers()) ? 0 : 1;
		for (int i = 0; i < cm.getParameterTypes().length; i++)
			paramNames.add(attr.variableName(i + pos));
		return paramNames;
	}
}